package pl.edu.pw.elka.spdb;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DataAccessException;

/**
 * Hello world!
 *
 */
public class App {
    /*
     * protected static DriverManagerDataSource dataSource;
     *
     * private static JdbcTemplate jdbcTemplate;
     */

    private static final String APPLICATION_CONTEXT_FILE = "pl/edu/pw/elka/spdb/applicationContext.xml";
    private static final int pointsCount = 100000;
    private static final int rectangleCount = 100000;
    private static final double maxRectangleX = 50.0;
    private static final double maxRectangleY = 50.0;
    private static final int groupCount = 100;
    private static final int rectangleGroupCount = 100;
    private static final int pathCount = 1000;
    private static final int pathSize = 10;
    private static final double pathElementsMaxDistance = 10;
    private static final double maxX = 1000.0;
    private static final double maxY = 1000.0;
    private static final int maxStringLength = 255;
    private static final int minStringLength = 1;
    private static final int pentagonCount = 10000;
    private static final int pentagonMaxRadius = 10;
    private static List<Point> equallySpreadPoints = new ArrayList<Point>();
    private static List<Point> groupedPoints = new ArrayList<Point>();
    private static List<Path> paths = new ArrayList<Path>();
    private static List<Rectangle> rectangles = new ArrayList<Rectangle>();
    private static List<Rectangle> groupedRectangles = new ArrayList<Rectangle>();
    private static List<Pentagon> pentagons = new ArrayList<Pentagon>();

    /*
     * static { dataSource = new DriverManagerDataSource();
     * dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
     * dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:orcl");
     * dataSource.setUsername("system"); dataSource.setPassword("agora");
	}
     */
    private static Random r = new Random();

    private static double getRandomDouble(double max) {
        return max * r.nextDouble();
    }

    private static int getRandomInt(int max) {
        return r.nextInt(max);
    }

    private static String getRandomString() {
        int stringLength = minStringLength + getRandomInt(maxStringLength - 1);
        RandomString randomString = new RandomString(stringLength);
        return randomString.nextString();
    }

    public static void main(String[] args) throws DataAccessException,
            ParseException {
        /*
         * jdbcTemplate = new JdbcTemplate(dataSource);
         * System.out.println("connected");
         */
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(APPLICATION_CONTEXT_FILE);

        SpdbDAO spdbDAO = (SpdbDAO) context.getBean("spdbDAO");

        generateData();
        //spdbDAO.insertPointsSpatial(equallySpreadPoints);
        //spdbDAO.insertPointsStandard(equallySpreadPoints);
       // spdbDAO.insertPointsSpatialGroup(groupedPoints);
       // spdbDAO.insertPointsStandardGroup(groupedPoints);
//        spdbDAO.insertPathsSpatial(paths);
//        spdbDAO.insertPathsStandard(paths);
        //spdbDAO.insertRectanglesStandard(rectangles);
       // spdbDAO.insertRectanglesSpatial(rectangles);
//        spdbDAO.insertGroupedRectanglesStandard(groupedRectangles);
//        spdbDAO.insertGroupedRectanglesSpatial(groupedRectangles);
        spdbDAO.insertPentagonsStandard(pentagons);
        spdbDAO.insertPentagonsSpatial(pentagons);
        
    }

    private static void generateData() {
        //generate equal spread
        for (int i = 0; i < pointsCount; i++) {
            Point tempPoint = new Point();
            tempPoint.setId(i);
            tempPoint.setX(getRandomDouble(maxX));
            tempPoint.setY(getRandomDouble(maxY));
            tempPoint.setNazwa(getRandomString());
            equallySpreadPoints.add(tempPoint);
        }

        //generate group spread
        for (int i = 0; i < groupCount; i++) {
            double groupCentreX = 50 + getRandomDouble(maxX - 100);
            double groupCentreY = 50 + getRandomDouble(maxY - 100);
            for (int j = 0; j < pointsCount / groupCount; j++) {
                Point tempPoint = new Point();
                tempPoint.setId(i * pointsCount / groupCount + j);
                tempPoint.setX(groupCentreX + getRandomDouble(maxX / 14) - 50.0);
                tempPoint.setY(groupCentreY + getRandomDouble(maxY / 14) - 50.0);
                tempPoint.setNazwa(getRandomString());
                groupedPoints.add(tempPoint);
            }
        }
        
        for (int i = 0; i < pathCount; i++) {
            Path p = new Path();
            p.setId(i);
            p.setNazwa(getRandomString());
            Double lastX = new Double(0);
            Double lastY = new Double(0);
            int path = 2 + getRandomInt(pathSize-2);
            for (int j = 0; j < path; j++) {
                Point pp = new Point();
                pp.setId(i * 100 + j);
                // losowanie punktu znajdujacego sie w obszarze -10,10 od poprzednio wylosowanego. dzieki temu sciezka bardziej skondensowana.
                pp.setX(((-1)^lastX.intValue()) * getRandomDouble(pathElementsMaxDistance) + lastX);
                pp.setY(((-1)^lastY.intValue()) * getRandomDouble(pathElementsMaxDistance) + lastY);
                pp.setNazwa(getRandomString());
                lastX = pp.getX();
                lastY = pp.getY();
                p.getPoints().add(pp);
            }
            paths.add(p);
        }
        
        //generate rectangles
        for (int i = 0; i < rectangleCount; i++) {
            double rectangleStartX = getRandomDouble(maxX - maxRectangleX);
            double rectangleStartY = getRandomDouble(maxY - maxRectangleY);
            double rectangleWidth = getRandomDouble(maxRectangleX);
            double rectangleHeight = getRandomDouble(maxRectangleY);
            String nazwa = getRandomString();
            Rectangle rectangle = new Rectangle(i, rectangleStartX, rectangleStartY, rectangleWidth, rectangleHeight, nazwa);
            rectangles.add(rectangle);
        }
        //generate rectangles group spread
        for (int i = 0; i < rectangleGroupCount; i++) {
            double groupCentreX = 50 + getRandomDouble(maxX - 100);
            double groupCentreY = 50 + getRandomDouble(maxY - 100);
            for (int j = 0; j < rectangleCount / rectangleGroupCount; j++) {
                double rectangleWidth = getRandomDouble(maxRectangleX);
                double rectangleHeight = getRandomDouble(maxRectangleY);
                String nazwa = getRandomString();
                Rectangle rectangle = new Rectangle(i * rectangleCount / groupCount + j, groupCentreX + getRandomDouble(maxX / 14) - 50.0, groupCentreY + getRandomDouble(maxY / 14) - 50.0, rectangleWidth, rectangleHeight, nazwa);
                
                groupedRectangles.add(rectangle);
            }
            
        }
        
        for (int i = 0; i < pentagonCount; i++) {
            double x = getRandomDouble(maxX * 100);
            double y = getRandomDouble(maxY * 100);
            Point[] points = new Point[5];
            double degree = 360;
            for (int j = 0; j < 5; j++){
                Point p = new Point();
                p.setX(x + pentagonMaxRadius * Math.cos(Math.toRadians(degree)));
                p.setY(x + pentagonMaxRadius * Math.sin(Math.toRadians(degree)));
                p.setNazwa(getRandomString());
                points[j] = p;
                degree = getRandomDouble(degree);                
            }
            pentagons.add(new Pentagon(i, points, getRandomString()));
        }

        System.out.println("Done.done");

    }
}